package juego;
import java.util.ArrayList;
import java.util.Iterator;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public abstract class Armado extends Vehiculo {
	
	//Atributos de instancia
	protected ArrayList<Disparable> armamento;
	protected CronometroEspera cronometro;
	
	//Metodos
	
	//Constructor. recibe una coordenada que representa el origen
	//un entero qu representa la resistencia inicial
	//y otro entero que representa el tiempo entre disparos
	public Armado(Coordenada coordenada, int vida, int tiempoDeEspera) {
		super(coordenada, vida);
		this.armamento = new ArrayList<Disparable>();
		this.cronometro = new CronometroEspera(tiempoDeEspera);
	}

	
	//recibe la lista de objetos.
	//agrega nuevos proyectiles a la lista, o lanza una excepcionMunicionAgotada
	//o una excepcionEsperaInsuficiente
	protected void disparar(ArrayList<Movil> listaDeObjetos){
		if (this.vivo){
			if (this.cronometro.puedoActuar()){
				Iterator<Disparable> iterador = armamento.iterator();
				while (iterador.hasNext()){
					Disparable unArma = iterador.next();
					Proyectil unProyectil = (unArma.disparar(this.ubicacion));
					listaDeObjetos.add(unProyectil);}
			}
			else{
				throw new ExcepcionEsperaInsuficiente();
			}
		}	
	}
	
	//Primero se mueve. Luego verifica si fue impactado,
	//y actua en consecuencia. Por ultimo, si no fue destruido dispara.
	public int vivir(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		int puntaje = 0;
		
		//Movimiento
		if (this.huyendo){
			this.huir();}
		else{
			this.movimientoPropio();}
		if (this.EstaFueraDelEscenario(this.ubicacion)){
			this.destruirse(listaDeMoviles);
		}else{
		//Impacto
		puntaje = (this.impactar(listaDeMoviles,listaDeBotines));
		if (!this.huyendo){
			try {
				this.disparar(listaDeMoviles);}
			catch(Exception e){
			}	
		}}
		return puntaje;
	}
	
	
	private void persistirCronometro(Document doc, Element elemento) {
		Element cronometro = this.cronometro.getElement(doc);
		elemento.appendChild(cronometro);
	}
	
	private void persistirArmamento(Document doc, Element elemento) {
		Element armamento = doc.createElement("Armamento");
		Iterator<Disparable> iterador = this.armamento.iterator();
		while (iterador.hasNext()) {
			Disparable arma = iterador.next();
			armamento.appendChild(arma.getElement(doc));
		}
		elemento.appendChild(armamento);
	}
	
	protected void persistirArmado(Document doc, Element elemento) {
		this.persistirArmamento(doc, elemento);
		this.persistirCronometro(doc, elemento);
		this.persistirVehiculo(doc, elemento);
	}
	
	protected static void recuperarArmado(Element element, Armado armado) {
		recuperarPropios(element, armado);
		Vehiculo.recuperarVehiculo(element, armado);
	}
	
	private static void recuperarPropios(Element element, Armado armado) {
		NodeList childs = element.getChildNodes();
		for (int i = 0; i < childs.getLength(); i++) {
			Node child = childs.item(i);
			if (child.getNodeName().equals("CronometroEspera")) {
				armado.cronometro = CronometroEspera.fromElement((Element) child);
			} 
			else if (child.getNodeName().equals("Armamento")) { 
				//obtengo a su vez la lista de hijos de este nodo
				NodeList listaNietos = child.getChildNodes();
				for (int j = 0; j < listaNietos.getLength();j++) {
					Node nieto = listaNietos.item(j);
					Disparable arma = recuperarArmamento(nieto);
					armado.armamento.add(arma);
				}
			}
		}
	}
					
					
				
	


	private static Disparable recuperarArmamento(Node nieto) {
		Disparable arma = null;
		String nombreNieto = nieto.getNodeName();
		
		if (nombreNieto.equals("ArmaLaser") ){
			arma = ArmaLaser.fromElement((Element)nieto);
		}
		else if (nombreNieto.equals("ArmaCohete") ){
			arma = ArmaCohete.fromElement((Element)nieto);
		}
		else if (nombreNieto.equals("ArmaTorpedoSimple") ){
			arma = ArmaTorpedoSimple.fromElement((Element)nieto);
		}
		else if (nombreNieto.equals("ArmaTorpedoRastreador") ){
			arma = ArmaTorpedoRastreador.fromElement((Element)nieto);
		}
		else if (nombreNieto.equals("ArmaTorpedoAdaptable") ){
			arma = ArmaTorpedoAdaptable.fromElement((Element)nieto);
		}
		
		return arma;
	}

	
}
		

